package com.occupation_health.shiro;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.jfinal.plugin.ehcache.CacheKit;
import com.occupation_health.model.Role;
import com.occupation_health.model.UserApi;

public class DbRealm extends AuthorizingRealm {

	public String getName() {
		return "DbRealm";
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken arg0) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) arg0;
		UserApi user = new UserApi().getByUserName(token.getUsername());

		String username = token.getUsername();
		AtomicInteger retryCount = CacheKit.get("passwordRetryCache", username); // 设定尝试登陆原子整数
		/* 尝试登陆次数判定 */
		if (null == retryCount) {
			retryCount = new AtomicInteger(0);
			CacheKit.put("passwordRetryCache", username, retryCount);
		}
		if (retryCount.incrementAndGet() > 5) {
			throw new AuthenticationException("该账号尝试登陆次数过多，将来的一段时间中将不能登陆");
		}
		/* 用户信息判定 */
		if (user != null) {
			if (!user.getStr("password").equals(
					String.valueOf(token.getPassword()))) {
				throw new AuthenticationException("用户名或密码错误");
			}
			return new SimpleAuthenticationInfo(user, user.getStr("password"),
					user.getStr("username"));
		} else {
			throw new AuthenticationException("用户名或密码错误");
		}
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		// TODO Auto-generated method stub
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		UserApi userInPrincipal = (UserApi) arg0.getPrimaryPrincipal();
		List<Role> roles = new Role().getUserRoles(userInPrincipal);
		for (Role role : roles) {
			info.addRole(role.getStr("name"));
		}
		return info;
	}

}
